home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 18 / CU Amiga Magazine's Super CD-ROM 18 (1997)(EMAP Images)(GB)[!][issue 1998-01].iso / CUCD / Programming / AmigaE / Src / OOmodules / sort / string.e < prev    next >
Encoding:
Text File  |  1996-11-02  |  17.7 KB  |  854 lines

  1. OPT MODULE
  2. OPT EXPORT
  3.  
  4. MODULE 'oomodules/sort','oomodules/sort/numbers/integer'
  5.  
  6. -> string.e: a derived object from 'sort' to handle
  7. -> strings.  Much more work needs to be done with this.
  8.  
  9. OBJECT string OF sort
  10. /****** string/--string-- ******************************************
  11.  
  12.     NAME 
  13.         string of sort
  14.  
  15.     ATTRIBUTES
  16.         item -- Pointer to the characters in this string. Is the first
  17.             element of a string chain that is modified by such functions
  18.             as cat(). Various functions work with the string chain, write()
  19.             for example reduces the size of it to one entry.
  20.  
  21.         len:PTR TO integer -- The length of this instance.
  22.  
  23.     NOTES
  24.       Through this document the following terms are used:
  25.           'String' -- this is the object we're talking about.
  26.           string -- a chain of characters ('this is one'). It is terminated
  27.               with a 0-byte. When there is a string required you may
  28.               also provide an estring.
  29.  
  30.     SEE ALSO
  31.         sort/--sort--
  32. ******************************************************************************
  33.  
  34. History
  35.  
  36.  
  37. */
  38.  item
  39.  len:PTR TO integer  -> I made this 'integer' in order to use the cmp in there.
  40. ENDOBJECT
  41.  
  42. -> size() gives an idea how much memory you can expect is used
  43.  
  44. PROC size() OF string IS 12
  45. /****** string/size ******************************************
  46.  
  47.     NAME 
  48.         size() -- Get size of instance.
  49.  
  50.     SYNOPSIS
  51.         string.size()
  52.  
  53.     FUNCTION
  54.         Returns the size of the instance.
  55.  
  56. ******************************************************************************
  57.  
  58. History
  59.  
  60.  
  61. */
  62.  
  63. -> name() returns the name of this kind of object.
  64.  
  65. PROC name() OF string IS 'String'
  66. /****** string/name ******************************************
  67.  
  68.     NAME 
  69.         name() -- Get name of object.
  70.  
  71.     SYNOPSIS
  72.         string.name()
  73.  
  74.     FUNCTION
  75.         Returns the name of the object. In this case 'String'.
  76.  
  77. ******************************************************************************
  78.  
  79. History
  80.  
  81.  
  82. */
  83.  
  84. -> We need to have a way to initialize 'len'.
  85.  
  86. PROC init() OF string
  87. /****** string/init ******************************************
  88.  
  89.     NAME 
  90.         init() -- Initialize the object.
  91.  
  92.     SYNOPSIS
  93.         string.init()
  94.  
  95.     FUNCTION
  96.         Allocates the Integer object used for len.
  97.  
  98.     SEE ALSO
  99.         integer/--integer--
  100. ******************************************************************************
  101.  
  102. History
  103.  
  104.  
  105. */
  106.  DEF tmp:PTR TO integer
  107.  NEW tmp.new()
  108.  self.len := tmp
  109. ENDPROC
  110.  
  111.  
  112. PROC select(opt,i) OF string
  113. /****** string/select ******************************************
  114.  
  115.     NAME 
  116.         select() -- Select action on initialization.
  117.  
  118.     SYNOPSIS
  119.         string.select(optionlist,index)
  120.  
  121.     FUNCTION
  122.         Recognizes the following items:
  123.           "set" -- calls self.cat() with the following item
  124.  
  125.           "sset" -- calls self.catString() with the following item
  126.  
  127.     INPUTS
  128.         optionlist -- The optionlist
  129.  
  130.         index -- The index of the optionlist
  131.  
  132.     SEE ALSO
  133.         object/select()
  134. ******************************************************************************
  135.  
  136. History
  137.  
  138.  
  139. */
  140.  DEF item
  141.  item:=ListItem(opt,i)
  142.  SELECT item
  143.   CASE "set"
  144.    INC i
  145.    self.cat(ListItem(opt,i))
  146.   CASE "sset"
  147.    INC i
  148.    self.catString(ListItem(opt,i))
  149.  ENDSELECT
  150. ENDPROC i
  151.  
  152. -> We have to dispose of the string and the 'len' pointer.
  153.  
  154. PROC end() OF string
  155. /****** string/end ******************************************
  156.  
  157.     NAME 
  158.       end() -- Global destructor.
  159.  
  160.     SYNOPSIS
  161.       string.end()
  162.  
  163.     FUNCTION
  164.       Frees used resources of the instance. It frees the string and the
  165.       length Integer.
  166.  
  167.     SEE ALSO
  168.       object/end()
  169. ******************************************************************************
  170.  
  171. History
  172.  
  173.  
  174. */
  175.  DEF tmp,str
  176.  str:=self.item
  177.  tmp:=self.len
  178.  DisposeLink(str)   -> get rid of the string.
  179.  END tmp     -> get rid of its length, too
  180. ENDPROC
  181.  
  182.  
  183. -> cmp() compares two strings quickly.. but it doesn't handle international characters.
  184. -> Many improvements could be made to this, I'm sure, but it has the virtue of being
  185. -> fairly quick.  Perhaps locale.library support would be nice.
  186.  
  187. PROC cmp(item:PTR TO string) OF string
  188. /****** string/cmp ******************************************
  189.  
  190.     NAME 
  191.         cmp() -- Compare to another 'String'.
  192.  
  193.     SYNOPSIS
  194.         string.cmp(item:PTR TO string)
  195.  
  196.     FUNCTION
  197.         Compares itself to another 'String' via E's builtin OstrCmp().
  198.  
  199.     INPUTS
  200.         item:PTR TO string -- The 'String' to compare to.
  201.  
  202.     RESULT
  203.         'Ordered String Compare' returns 1 if string2>string1, 0 for equal
  204.         and 1 for less.
  205.  
  206.     NOTES
  207.         cmp() compares two strings quickly.. but it doesn't handle
  208.         international characters. Many improvements could be made to this,
  209.         I'm sure, but it has the virtue of being fairly quick.  Perhaps
  210.         locale.library support would be nice.
  211.  
  212.     SEE ALSO
  213.         E reference/OstrCmp()
  214. ******************************************************************************
  215.  
  216. History
  217.  
  218.  
  219. */
  220.  DEF i,inner,outer
  221.  inner:=self.write()
  222.  outer:=item.write()
  223.  RETURN OstrCmp(inner,outer)
  224. ENDPROC
  225.  
  226. -> set() lets you put a value into the string.
  227.  
  228. PROC set(in) OF string
  229. /****** string/set ******************************************
  230.  
  231.     NAME 
  232.         set() -- Set the 'String''s contents.
  233.  
  234.     SYNOPSIS
  235.         string.set(in)
  236.  
  237.     FUNCTION
  238.         Sets the contents of itself. An already present string will be freed
  239.         first.
  240.  
  241.     INPUTS
  242.         in -- Pointer to normal 0-terminated string. Could be an estring
  243.             as well.
  244.  
  245.     EXAMPLE
  246.  
  247.         PROC main()
  248.         DEF string:PTR TO string
  249.  
  250.           NEW string.new()    -> allocate and initialize
  251.           string.set('build no schools, construct no roads')
  252.           string.cat(' mark them as fools, let ignorance rule')
  253.  
  254.           WriteF('\s\n', string.write())  ->get string and write it
  255.  
  256.         ENDPROC
  257.  
  258.     SEE ALSO
  259.         cat()
  260. ******************************************************************************
  261.  
  262. History
  263.  
  264.  
  265. */
  266.   IF self.item
  267.     DisposeLink(self.item)
  268.     self.item := NIL
  269.   ENDIF
  270.  
  271.   self.len.set(0)
  272.   self.cat(in)
  273.  
  274. ENDPROC
  275.  
  276. -> length() returns the length of the string.
  277.  
  278. PROC length() OF string
  279. /****** string/length ******************************************
  280.  
  281.     NAME 
  282.         length() -- Get length of 'String'.
  283.  
  284.     SYNOPSIS
  285.         string.length()
  286.  
  287.     FUNCTION
  288.         Gets the length of itself.
  289.  
  290.     RESULT
  291.         Length of itself.
  292.  
  293.     SEE ALSO
  294.         integer/get()
  295. ******************************************************************************
  296.  
  297. History
  298.  
  299.  
  300. */
  301.  RETURN self.len.get()
  302. ENDPROC
  303.  
  304.  
  305. PROC write() OF string
  306. /****** string/write ******************************************
  307.  
  308.     NAME 
  309.       write() -- Turn 'String' into printable string.
  310.  
  311.     SYNOPSIS
  312.       string.write()
  313.  
  314.     FUNCTION
  315.       If you want to turn 'String' into a normal string (or estring) so
  316.       you can work with it as if it was a normal series of characters you
  317.       should call this function. It returns a pointer to an estring that
  318.       contains 'String''s contents.
  319.  
  320.     RESULT
  321.       Pointer to estring containing
  322.  
  323.     NOTES
  324.       Works on the internal string chain and builds one continuous string
  325.       from it. The string chain contains only one entry after the call
  326.       of this proc.
  327.  
  328.     EXAMPLE
  329.         PROC main()
  330.         DEF string:PTR TO string
  331.  
  332.           NEW string.new()    -> allocate and initialize
  333.           string.set('build no schools, construct no roads')
  334.           string.cat('mark them as fools, let ignorance rule')
  335.  
  336.           WriteF('\s\n', string.write())  ->get string and write it
  337.  
  338.         ENDPROC
  339.  
  340. ******************************************************************************
  341.  
  342. History
  343.  
  344.  
  345. */
  346.  DEF out,this,next=0
  347.  this:=self.item
  348.  next:=Next(this)
  349.  IF next
  350.   out:=String(self.len.get()+1)
  351.   WHILE next
  352.    next:=Next(this)
  353.    StrAdd(out,this)
  354.    this:=next
  355.   ENDWHILE
  356.   DisposeLink(self.item)
  357.   self.item:=out
  358.  ELSE
  359.   out:=self.item
  360.  ENDIF
  361. ENDPROC out
  362.  
  363.  
  364. PROC get() OF string
  365. /****** string/get ******************************************
  366.  
  367.     NAME 
  368.         get() -- Get 'String''s item.
  369.  
  370.     SYNOPSIS
  371.         string.get()
  372.  
  373.     FUNCTION
  374.         Gets its item. Only for internal use, if you want to print the 'String'
  375.         or work with it you have to call write().
  376.  
  377.     RESULT
  378.         string.item
  379.  
  380.     SEE ALSO
  381.         write()
  382. ******************************************************************************
  383.  
  384. History
  385.  
  386.  
  387. */
  388.  RETURN self.item
  389. ENDPROC
  390.  
  391.  
  392. PROC cat(in) OF string
  393. /****** string/cat ******************************************
  394.  
  395.     NAME 
  396.         cat() -- Add normal string.
  397.  
  398.     SYNOPSIS
  399.         string.cat(in)
  400.  
  401.     FUNCTION
  402.         Adds a normal string to itself. This can be a 0-terminated array of
  403.         char or an estring. The string is copied and added at the end.
  404.  
  405.     INPUTS
  406.         in -- string to add.
  407.  
  408.     RESULT
  409.         Pointer to the estring copy of the string to add.
  410.  
  411.     EXAMPLE
  412.         PROC main()
  413.         DEF string:PTR TO string
  414.  
  415.           NEW string.new()    -> allocate and initialize
  416.           string.set('build no schools, construct no roads ')
  417.           string.cat('mark them as fools, let ignorance rule')
  418.  
  419.           WriteF('\s\n', string.write())  ->get string and write it
  420.  
  421.         ENDPROC
  422.  
  423.  
  424.     SEE ALSO
  425.         concat(), catString(), concatString()
  426. ******************************************************************************
  427.  
  428. History
  429.  
  430.  
  431. */
  432.  DEF tmp,count
  433.  count:=StrLen(in)
  434.  tmp := String(count+1)
  435.  StrCopy(tmp,in)
  436.  self.concat(tmp,count)
  437. ENDPROC tmp
  438.  
  439.  
  440. PROC concat(in,count=0) OF string
  441. /****** string/concat ******************************************
  442.  
  443.     NAME 
  444.         concat() -- Add string to the internal string chain.
  445.  
  446.     SYNOPSIS
  447.         string.concat(in,count=0)
  448.  
  449.     FUNCTION
  450.         Adds a string to the internal string chain. The length is set to the
  451.         new length.
  452.  
  453.     INPUTS
  454.         in -- normal string to add.
  455.  
  456.         count -- the length of in. Can be left 0 normally, in that case the
  457.             length is found out by StrLen().
  458.  
  459.     NOTES
  460.         Mainly for internal use. Mortal beings use catString().
  461.  
  462.     SEE ALSO
  463.         cat(), concatString(), catString()
  464. ******************************************************************************
  465.  
  466. History
  467.  
  468.  
  469. */
  470.  DEF tmp,next
  471.  IF self.item
  472.   next:=tmp:=self.item
  473.   WHILE next
  474.    IF next:=Next(tmp) THEN tmp:=next
  475.   ENDWHILE
  476.   Link(tmp,in)
  477.  ELSE
  478.   self.item:=in
  479.  ENDIF
  480.  IF count THEN self.len.add(count) ELSE self.len.add(StrLen(in))
  481. ENDPROC
  482.  
  483.  
  484. PROC concatString(in:PTR TO string) OF string
  485. /****** string/concatString ******************************************
  486.  
  487.     NAME 
  488.         concatString() -- Add 'String' to the internal string chain.
  489.  
  490.     SYNOPSIS
  491.         string.concatString(in:PTR TO string)
  492.  
  493.     FUNCTION
  494.         Adds a 'String' to the internal string chain. The length is set to the
  495.         new length.
  496.  
  497.     INPUTS
  498.         in -- 'String' to add.
  499.  
  500.     RESULT
  501.         Pointer to new string or 0 if in was NIL.
  502.  
  503.     NOTES
  504.         Mainly for internal use. Mortal beings use catString().
  505.  
  506.     SEE ALSO
  507.         cat(), concat(), catString()
  508. ******************************************************************************
  509.  
  510. History
  511.  
  512.  
  513. */
  514.  IF in THEN self.concat(in.item,in.length()) ELSE RETURN 0
  515. ENDPROC self.item
  516.  
  517.  
  518. PROC catString(in:PTR TO string) OF string
  519. /****** string/catString ******************************************
  520.  
  521.     NAME 
  522.         catString() -- Cat a 'String' to another.
  523.  
  524.     SYNOPSIS
  525.         catString(in:PTR TO string)
  526.  
  527.     FUNCTION
  528.         Puts a 'String' at the end of itself.
  529.  
  530.     INPUTS
  531.         in:PTR TO string -- 'String' to add.
  532.  
  533.     RESULT
  534.         item of itself.
  535.  
  536.     SEE ALSO
  537.         concatString()
  538.  
  539. ******************************************************************************
  540.  
  541. History
  542.  
  543.  
  544. */
  545.  IF in THEN self.cat(in.write()) ELSE RETURN 0
  546. ENDPROC self.item
  547.  
  548.  
  549. PROC upper() OF string
  550. /****** string/upper ******************************************
  551.  
  552.     NAME 
  553.       upper() -- Change the case of each character to upper.
  554.  
  555.     SYNOPSIS
  556.       string.upper()
  557.  
  558.     FUNCTION
  559.       The case of each character in the 'String' is turned to upper.
  560.  
  561.     NOTES
  562.       Calls write().
  563.  
  564. ******************************************************************************
  565.  
  566. History
  567.  
  568.  
  569. */
  570.  self.write()
  571.  UpperStr(self.item)
  572. ENDPROC
  573.  
  574.  
  575. PROC lower() OF string
  576. /****** string/lower ******************************************
  577.  
  578.     NAME 
  579.       lower() -- Change the case of each character to lower.
  580.  
  581.     SYNOPSIS
  582.       string.lower()
  583.  
  584.     FUNCTION
  585.       The case of each character in the 'String' is turned to lower.
  586.  
  587.     NOTES
  588.       Calls write().
  589.  
  590. ******************************************************************************
  591.  
  592. History
  593.  
  594.  
  595. */
  596.  self.write()
  597.  LowerStr(self.item)
  598. ENDPROC
  599.  
  600.  
  601. PROC trimmed() OF string
  602. /****** string/trimmed ******************************************
  603.  
  604.     NAME 
  605.         trimmed() -- Trim whitespace from 'String'.
  606.  
  607.     SYNOPSIS
  608.         string.trimmed()
  609.  
  610.     FUNCTION
  611.         Trims itself, i.e. returns a string that starts with the first
  612.         non-whitespace character.
  613.  
  614.     RESULT
  615.         Pointer to 'String' which contains the trimmed contents of self.
  616.         It is a newly created 'String', you have to END() it yourself when
  617.         you don't need it anymore.
  618.  
  619. ******************************************************************************
  620.  
  621. History
  622.  
  623.  
  624. */
  625.  DEF out,tmp,spank:PTR TO string
  626.  self.write()
  627.  out:=String(self.length()+1)
  628.  tmp:=TrimStr(self.item)
  629.  StrCopy(out,tmp)
  630.  NEW spank.new(["set",out])
  631.  DisposeLink(out)
  632. ENDPROC spank
  633.  
  634.  
  635. PROC find(in:PTR TO string) OF string
  636. /****** string/find ******************************************
  637.  
  638.     NAME 
  639.         find() -- Test if 'String' is in 'String'.
  640.  
  641.     SYNOPSIS
  642.         string.find(in:PTR TO string)
  643.  
  644.     FUNCTION
  645.         Searches a 'String' in itself.
  646.  
  647.     INPUTS
  648.         in:PTR TO string -- 'String' to search for
  649.  
  650.     RESULT
  651.         TRUE if in is in self, FALSE otherwise.
  652.  
  653.     NOTES
  654.         Calls write() on in.
  655.  
  656. ******************************************************************************
  657.  
  658. History
  659.  
  660.  
  661. */
  662.  DEF me,he
  663.  me:=self.write()
  664.  he:=in.write()
  665.  RETURN IF InStr(me,he,0)<>-1 THEN TRUE ELSE FALSE
  666. ENDPROC
  667.  
  668.  
  669. PROC asInteger() OF string
  670. /****** string/asInteger ******************************************
  671.  
  672.     NAME 
  673.         asInteger() -- Turn 'String' to Integer
  674.  
  675.     SYNOPSIS
  676.         string.asInteger()
  677.  
  678.     FUNCTION
  679.         Tries to turn itself to an Integer.
  680.  
  681.     RESULT
  682.         PTR TO integer -- The integer that was in 'String'.
  683.  
  684.     NOTES
  685.         Only call when you know that the string contains an integer. There
  686.         is actually no way to test if the proc ran successful over the
  687.         strings contents.
  688.  
  689.         Call write().
  690.  
  691. ******************************************************************************
  692.  
  693. History
  694.  
  695.  
  696. */
  697.  DEF valstring,value,read,out:PTR TO integer
  698.  valstring:=self.write()
  699.  value,read:=Val(valstring)
  700.  NEW out.new(["set",value])
  701. ENDPROC out
  702.  
  703.  
  704. PROC right(n) OF string
  705. /****** string/right ******************************************
  706.  
  707.     NAME 
  708.         right() -- Get right part of 'String'.
  709.  
  710.     SYNOPSIS
  711.         string.right(length)
  712.  
  713.     FUNCTION
  714.         Gets part from the right side of itself and builds a new 'String'
  715.         from it.
  716.  
  717.     INPUTS
  718.         length -- get how many characters.
  719.  
  720.     RESULT
  721.         PTR TO string -- a freshly created 'String' that contains the desired
  722.             string part.
  723.  
  724.     EXAMPLE
  725.  
  726.         PROC main()
  727.         DEF mainString:PTR TO string,
  728.             partOfString:PTR TO string
  729.  
  730.           NEW mainString.new(["set", 'down in Los Angeles'])
  731.  
  732.           partOfString := mainString.right(11)
  733.  
  734.           WriteF('\s\n', partOfString.write())
  735.  
  736.           END partOfString
  737.           END mainString
  738.         ENDPROC
  739.  
  740.     SEE ALSO
  741.         left(), middle()
  742. ******************************************************************************
  743.  
  744. History
  745.  
  746.  
  747. */
  748.  RETURN self.middle(self.length()-n-1,n)
  749. ENDPROC
  750.  
  751.  
  752. PROC middle(pos,len=ALL) OF string
  753. /****** string/middle ******************************************
  754.  
  755.     NAME 
  756.         middle() -- Get a part of 'String'.
  757.  
  758.     SYNOPSIS
  759.         string.middle(position,length)
  760.  
  761.     FUNCTION
  762.         Gets a part from itself and builds a new 'String' from it.
  763.  
  764.     INPUTS
  765.         position -- Start at what position of itself.
  766.  
  767.         length -- get how many characters from position up to the end.
  768.  
  769.     RESULT
  770.         PTR TO string -- a freshly created 'String' that contains the desired
  771.             string part.
  772.  
  773.     EXAMPLE
  774.  
  775.         PROC main()
  776.         DEF mainString:PTR TO string,
  777.             partOfString:PTR TO string
  778.  
  779.           NEW mainString.new(["set", 'down in Los Angeles'])
  780.  
  781.           partOfString := mainString.middle(5,2)
  782.  
  783.           WriteF('\s\n', partOfString.write())
  784.  
  785.           END partOfString
  786.           END mainString
  787.         ENDPROC
  788.  
  789.     SEE ALSO
  790.         left(), right()
  791. ******************************************************************************
  792.  
  793. History
  794.  
  795.  
  796. */
  797.  DEF out:PTR TO string,buffer,other
  798.  IF pos>=self.length() THEN RETURN 0
  799.  buffer:=String(IF len=ALL THEN self.length()-pos ELSE len)
  800.  other:=self.write()
  801.  MidStr(buffer,other,pos,len)
  802.  NEW out.new(["set",buffer])
  803.  DisposeLink(buffer)
  804. ENDPROC out
  805.  
  806.  
  807. PROC left(n) OF string
  808. /****** string/left ******************************************
  809.  
  810.     NAME 
  811.         left() -- Get left part of 'String'.
  812.  
  813.     SYNOPSIS
  814.         string.left(length)
  815.  
  816.     FUNCTION
  817.         Gets a part from the left side of itself and builds a new 'String'
  818.         from it.
  819.  
  820.     INPUTS
  821.         length -- get how many characters.
  822.  
  823.     RESULT
  824.         PTR TO string -- a freshly created 'String' that contains the desired
  825.             string part.
  826.  
  827.     EXAMPLE
  828.  
  829.         PROC main()
  830.         DEF mainString:PTR TO string,
  831.             partOfString:PTR TO string
  832.  
  833.           NEW mainString.new(["set", 'down in Los Angeles'])
  834.  
  835.           partOfString := mainString.left(4)
  836.  
  837.           WriteF('\s\n', partOfString.write())
  838.  
  839.           END partOfString
  840.           END mainString
  841.         ENDPROC
  842.  
  843.     SEE ALSO
  844.         middle(), right()
  845. ******************************************************************************
  846.  
  847. History
  848.  
  849.  
  850. */
  851.  RETURN self.middle(0,n)
  852. ENDPROC
  853.  
  854.